package team1.project2.metrics;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import com.vmware.vim25.PerfEntityMetric;
import com.vmware.vim25.PerfEntityMetricBase;
import com.vmware.vim25.PerfMetricId;
import com.vmware.vim25.PerfMetricIntSeries;
import com.vmware.vim25.PerfMetricSeries;
import com.vmware.vim25.PerfProviderSummary;
import com.vmware.vim25.PerfQuerySpec;
import com.vmware.vim25.PerfSampleInfo;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.PerformanceManager;
import com.vmware.vim25.mo.ServiceInstance;

@Path ("/get")
public class MetricsCollector {
	Folder rootFolder;
	//int[] key = {1,2,3,5,6,7,12,16,17,18,65537,65538,65539,65586,65587,65588,65628,131073,131074,131075,196609,196610,196611,262144,262145,262146,262148,524291,524292,589826,589827,589830,589831,720896};
	Properties prop;
	
	@GET
	@Path ("logmetrics/syslogs/kwcount")
	@Produces ("application/json")
	public Vector<KeywordSearch> getLogMetrics(@QueryParam("keyword") String s){
		LogDAO ld = new LogDAO();
		Vector<KeywordSearch> ks = ld.getKeywordOccurences(s);
		return ks;
	}
	
	@GET
	@Path ("logmetrics/syslogs/lines")
	@Produces ("application/json")
	public ArrayList<LineSearch> getSysLogLinesMetrics(@QueryParam("keyword") String s){
		LogDAO ld = new LogDAO();
		ArrayList<LineSearch> ks = ld.getLinesFromSysLogs(s);
		return ks;
	}
	
	@GET
	@Path ("logmetrics/kernelLogs/cpu")
	@Produces ("application/json")
	public ArrayList<VMKernelLogs> getCPUMetrics(@QueryParam("cpu") String cpu){
		LogDAO ld = new LogDAO();
		ArrayList<VMKernelLogs> kl = ld.getFromKernelCPU(cpu);
		return kl;
	}
	
	@GET
	@Path ("logmetrics/kernelWarnings/cpu")
	@Produces ("application/json")
	public ArrayList<VMKernelLogs> getFromKernelWarningCPU(@QueryParam("cpu") String cpu){
		LogDAO ld = new LogDAO();
		ArrayList<VMKernelLogs> kl = ld.getFromKernelWarningCPU(cpu);
		return kl;
	}
	  
	
	@GET
	@Path ("metrics")
	@Produces ("application/json")
	public Metrics collectMetrics() {
		Metrics metrics = null;
		prop = new Properties();
		URL adminHost;
		try {
			prop.load(new FileInputStream("C:\\Documents and Settings\\family.PDPHOME-A54F0A5\\Desktop\\metricsconfig.properties"));
			//prop.load(new FileInputStream("/home/vm1cmpe283/cmpe283/metricsconfig.properties"));
			adminHost = new URL("https://130.65.157.67/sdk");
			ServiceInstance	si1 = new ServiceInstance(adminHost, "Administrator", "12!@qwQW", true);
			rootFolder = si1.getRootFolder();
		    //HostSystem hs = (HostSystem) new InventoryNavigator(rootFolder).searchManagedEntity("HostSystem", "cirrus1.engr.sjsu.edu");
		    URL hostURL = new URL("https://130.65.157.126/sdk");
		    ServiceInstance si = new ServiceInstance(hostURL, "root", "12!@qwQW", true);   
		    ManagedEntity vm = new InventoryNavigator(si.getRootFolder()).searchManagedEntity("VirtualMachine", "VM_3");
				
		    if(vm == null)
		    {
		      System.out.println("Virtual Machine VM_3 cannot be found.");
		      si.getServerConnection().logout();
		      return null;
		    }

		    PerformanceManager perfMgr = si.getPerformanceManager();

		    PerfProviderSummary pps = perfMgr.queryPerfProviderSummary(vm);
		    int refreshRate = pps.getRefreshRate().intValue();

		    // retrieve all the available perf metrics for vm
		    PerfMetricId[] pmis = perfMgr.queryAvailablePerfMetric(
		        vm, null, null, refreshRate);

		    PerfQuerySpec qSpec = createPerfQuerySpec(
		        vm, pmis, 3, refreshRate);

		    
		      PerfEntityMetricBase[] pValues = perfMgr.queryPerf(
		        new PerfQuerySpec[] {qSpec});
		      if(pValues != null)
		      {
		    	  for(int i=0; i<pValues.length; ++i) 
		  	    {
		    		  System.out.println("Entity length = " + pValues.length);  
		  	      String entityDesc = pValues[i].getEntity().getType() 
		  	          + ":" + pValues[i].getEntity().get_value();
		  	      System.out.println("Entity:" + entityDesc);
		  	      if(pValues[i] instanceof PerfEntityMetric)
		  	      {
		  	       metrics =  printPerfMetric((PerfEntityMetric)pValues[i]);
		  	      }
		  	      
		  	      else
		  	      {
		  	        System.out.println("UnExpected sub-type of " +
		  	        		"PerfEntityMetricBase.");
		  	        
		  	      }
		  	    }
		      }
//		      System.out.println("Sleeping 60 seconds...");
//		      Thread.sleep(refreshRate*3*1000);
		    
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return metrics;
		
	    }
	  


private PerfQuerySpec createPerfQuerySpec(ManagedEntity me, 
	      PerfMetricId[] metricIds, int maxSample, int interval)
	  {
	    PerfQuerySpec qSpec = new PerfQuerySpec();
	    qSpec.setEntity(me.getMOR());
	    // set the maximum of metrics to be return
	    // only appropriate in real-time performance collecting
	    qSpec.setMaxSample(new Integer(maxSample));
//	    qSpec.setMetricId(metricIds);
	    // optionally you can set format as "normal"
	    qSpec.setFormat("normal");
	    // set the interval to the refresh rate for the entity
	    qSpec.setIntervalId(new Integer(interval));
	 
	    return qSpec;
	  }
  
	  private Metrics printPerfMetric(PerfEntityMetric pem)
	  {
		  Metrics metrics = new Metrics();
		  String delimiter = ",";
		  String temp[];
	    PerfMetricSeries[] vals = pem.getValue();
	    PerfSampleInfo[]  infos = pem.getSampleInfo();
	    
	    //System.out.println("Sampling Times and Intervales:");
	    for(int i=0; infos!=null && i <infos.length; i++)
	    {
	    	metrics.setSampleTime(infos[i].getTimestamp().getTime());
	    	metrics.setInterval(infos[i].getInterval());
//	      System.out.println("Sample time: " + infos[i].getTimestamp().getTime());
//	      System.out.println("Sample interval (sec):" + infos[i].getInterval());
	    }
	    System.out.println("Sample values:");
	    for(int j=0; vals!=null && j<vals.length; ++j)
	    {
	    	Counter counter = new Counter();
	    	int i = vals[j].getId().getCounterId();
	    	counter.setCounterId(i);
	    	
		    	//for (int l = 0; l<key.length;l++){	    		
				    //if (i == key[l]){
				    if (prop.getProperty(String.valueOf(i))!= null){
				    	String value = prop.getProperty(String.valueOf(i));
				    	temp = value.split(delimiter);
				    	counter.setName(temp[0]);
				    	counter.setUnit(temp[1]);
				      System.out.println("Perf counter ID:" 
				          + vals[j].getId().getCounterId());
				      System.out.println("Device instance ID:" 
				          + vals[j].getId().getInstance());
				      
					      if(vals[j] instanceof PerfMetricIntSeries)
						      {
						        PerfMetricIntSeries val = (PerfMetricIntSeries) vals[j];
						        long[] longs = val.getValue();
						        if (longs.length == 3){
						        	counter.setSample1(longs[0]);
						        	counter.setSample2(longs[1]);
						        	counter.setSample3(longs[2]);
						        }			        
						      }
					      metrics.setCounter(counter);
					     
				    	}
		    	//}
	    }
	    return metrics;
	  }
	    
	  
}

